#include <string>
#include <string.h>
#include <iostream>

#include <QFile>
#include <QTextStream>

#include <QString>
#include <QStringList>
// #include <QSharedMemory>

#include "profinet/initialization.h"
#include "profinet/profinet_device.h"
#include "p-net/pnet_api.h"
#include "test/test.h"

using namespace aubo::pi;

#define APP_PRIORITY                   15
// #define APP_STACKSIZE                  4096        /* bytes */
#define APP_STACKSIZE                  40960        /* bytes */
#define APP_MAIN_SLEEPTIME_US          5000*1000

namespace aubo {

namespace pi {

QFile file_log;
QTextStream text_stream;

}

}

int main(int argc, char *argv[])
{
    app_data_t app_data;
    memset(&app_data, 0, sizeof(app_data));
    app_data.alarm_allowed = true;
    app_data.main_arep = UINT32_MAX;
    // 初始化寄存器。
    if (!initializeAppData(app_data))
    {
        std::cout << "[ERROR] Failed to initialize application data." << std::endl;
        return -1;
    }

    file_log.setFileName("./log");
    if (file_log.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
    {
        std::cout << "Open log file." << std::endl;
        text_stream.setDevice(&file_log);
    }
    else
    {
        std::cout << "[ERROR] Failed to open log file." << std::endl;
        return -1;
    }

    // Prepare stack config with IP address, gateway, station name etc
    // Note that these members are set by the main:
    //    cb_arg
    //    im_0_data.order_id
    //    im_0_data.im_serial_number
    //    eth_addr.addr
    //    ip_addr
    //    ip_gateway
    //    ip_mask
    //    station_name
    pnet_cfg_t pnet_default_cfg;
    pnetAdjustStackConfiguration(&pnet_default_cfg);
    pnet_default_cfg.cb_arg = (void *) &app_data;

    std::string ethernet_interface;
    if (!initializeStackConfiguration(pnet_default_cfg, ethernet_interface))
    {
        std::cout << "[ERROR] Failed to initialize stack configuration." << std::endl;
        return -1;
    }

    /* Initialize profinet stack */
    pnet_t * net = pnet_init(ethernet_interface.data(), TICK_INTERVAL_US, &pnet_default_cfg);
    if (net == NULL)
    {
       printf("Failed to initialize p-net. Do you have enough Ethernet interface permission?\n");
       return -1;
    }

    pnetPlugDAP(net, &app_data);

    /* Initialize timer and Profinet stack */
    app_data.main_events = os_event_create();
    app_data.main_timer  = os_timer_create(TICK_INTERVAL_US, mainTimerTick, (void*)&app_data, false);

    app_data_and_stack_t app_data_and_stack;
    app_data_and_stack.appdata = &app_data;
    app_data_and_stack.net = net;
    os_thread_create("pnetMainLoop", APP_PRIORITY, APP_STACKSIZE, pnetMainLoop, (void*)&app_data_and_stack);

    os_timer_start(app_data.main_timer);

    for( ; ; )
       os_usleep(APP_MAIN_SLEEPTIME_US);

    return 0;
}
